/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package hxg.http.server.handler.impl;

import com.jcraft.jsch.Channel;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.commons.net.telnet.TelnetClient;

/**
 *
 * @author hstel-hxg
 */
public final class RemoteStreamClient {

    String token;
    long createTime;
    long lastflashTime;
    Channel c;
    TelnetClient tc;
    CacheOutPutStream cos;
    OutputStream os;

    public RemoteStreamClient(String token, Channel c) throws IOException {
        this.token = token;
        createTime = System.currentTimeMillis();
        this.c = c;
        this.os = c.getOutputStream();
        cos = new CacheOutPutStream(c.getInputStream());
    }

    public RemoteStreamClient(String token, TelnetClient tc) throws IOException {
        this.token = token;
        createTime = System.currentTimeMillis();
        this.tc = tc;
        cos = new CacheOutPutStream(tc.getInputStream());
    }

    public InputStream getInputStream() throws IOException {
        if (tc != null) {
            return tc.getInputStream();
        }
        if (c != null) {
            return c.getInputStream();
        }
        return null;
    }

    public OutputStream getOutputStream() throws IOException {
        if (tc != null) {
            return tc.getOutputStream();
        }
        if (c != null) {
            return c.getOutputStream();
        }
        return null;
    }

    public boolean isConnected() {
        if (tc != null) {
            return tc.isConnected();
        }
        if (c != null) {
            return c.isConnected();
        }
        return false;
    }

    public byte[] getDataOfBytes() {
        return cos.getCache();
    }

    public void disconnect() throws IOException {
        if (tc != null) {
            tc.disconnect();
        }
        if (c != null) {
            c.disconnect();
        }
    }

    public String getData() {
        return new String(cos.getCache());
    }

    class CacheOutPutStream extends OutputStream {

        InputStream is;
        ConcurrentLinkedQueue<Byte> list = new ConcurrentLinkedQueue<>();

        public CacheOutPutStream(InputStream is) throws IOException {
            this.is = is;
            startDaemonThread();
        }

        private void startDaemonThread() throws IOException {
            Thread t = new Thread(() -> {
                while (true) {
                    try {
                        if (is.available() > 0) {
                            this.write(is.read());
                        } else {
                            TimeUnit.MILLISECONDS.sleep(2);
                        }
                    } catch (IOException | InterruptedException ex) {
                        Logger.getLogger(RemoteStreamClient.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
            });
            t.setDaemon(true);
            t.start();
        }

        @Override
        public void write(int b) throws IOException {
            list.offer((byte) b);
        }

        public byte[] getCache() {
            byte bytes[] = new byte[list.size()];
            for (int i = 0; i < bytes.length; i++) {
                bytes[i] = list.poll();
            }
            System.out.println(new String(bytes));
            return bytes;
        }

    }



}
